package cn.luow.freemarker.service;

import cn.luow.freemarker.model.FtlInfo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.SneakyThrows;
import org.springframework.context.event.EventListener;
import org.ssssssss.magicapi.core.event.FileEvent;
import org.ssssssss.magicapi.core.event.GroupEvent;
import org.ssssssss.magicapi.core.service.AbstractMagicDynamicRegistry;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.service.MagicResourceStorage;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FreemarkerMagicDynamicRegistry extends AbstractMagicDynamicRegistry<FtlInfo> {
    @Resource
    private MagicResourceService magicResourceService;
    private Map<String,Template> templateMap ;
    private Configuration cf ;

    public FreemarkerMagicDynamicRegistry(MagicResourceStorage<FtlInfo> magicResourceStorage) {
        super(magicResourceStorage);
    }

    @EventListener(condition = "#event.type == 'freemarker'")
    public void onFileEvent(FileEvent event) {
        processEvent(event);
    }

    @EventListener(condition = "#event.type == 'freemarker'")
    public void onGroupEvent(GroupEvent event) {
        processEvent(event);
    }

    @SneakyThrows
    @Override
    public boolean register(FtlInfo entity) {
        if(templateMap==null){
            templateMap = new ConcurrentHashMap();
            cf=new Configuration(Configuration.VERSION_2_3_28);
            cf.setDefaultEncoding("UTF-8");
        }
        unregister(entity);
        String path = "/"+magicResourceService.getGroupPath(entity.getGroupId())+"/"+entity.getPath();
        String script = entity.getScript();
        String reg = "<#include[^<>]*?\\s['\"]?@([^'\"]*)['\"]?\\s?.*?>";
        Matcher m = Pattern.compile(reg).matcher(script);
        while (m.find()) {
            String r = m.group(1);
            String rep = this.getMapping(r).getScript();
            script = script.replaceFirst("<#include[^<>]*?\\s['\"]?@"+r+"['\"]?\\s?.*?>",rep);
        }

        Template template=new Template(path ,script ,cf);
        templateMap.put(path,template);
        return super.register(entity);
    }

    @Override
    public boolean unregister(FtlInfo entity){
        if(templateMap.containsKey(entity)){
            templateMap.remove(entity);
        }
        return super.unregister(entity);
    }

    @Override
    protected boolean register(MappingNode<FtlInfo> mappingNode) {

        return super.register(mappingNode);
    }

    @Override
    protected void unregister(MappingNode<FtlInfo> mappingNode) {
        super.unregister(mappingNode);
    }
    public Template get(String path){
        return templateMap.get(path);
    }
}
